%module shift_and_squeeze

%{
#define SWIG_FILE_WITH_INIT

#include <stdio.h>
#include <numpy/arrayobject.h>
#include "../c_doas/shift_and_squeeze.h"
#include "../c_doas/autodealloc_numpy.h"
%}

%init %{
import_array();
import_autodealloc_numpy();
%}

%inline %{
typedef struct ShiftAndSqueezer {
    int num_refs;
    int fit_window_length;
    sns_data_t * __sns_data;
    
} ShiftAndSqueezer;
%}

%extend ShiftAndSqueezer {

    ShiftAndSqueezer(PyObject *refs, double *IN_ARRAY1, int DIM1){
        //TODO - check that refs is a sequence!
        int i;
        PyObject *current_ref;
        PyObject *counts_arr, *wavelength_arr;
        ShiftAndSqueezer *obj = malloc(sizeof(ShiftAndSqueezer));
        
        //unpack the reference objects and retrieve their wavelengths and counts
        obj->num_refs = PyObject_Length(refs);
        
        //create an array for the pointers
        int *ref_lengths = malloc(obj->num_refs * sizeof(int));
        double **ref_ptrs = malloc(obj->num_refs * sizeof(double *));
        double **ref_wavelength_ptrs = malloc(obj->num_refs * sizeof(double *));
        
        for (i=0; i<obj->num_refs; i++){
        	current_ref = PySequence_GetItem(refs, (Py_ssize_t) i);
        	
        	//TODO - check that the ref has the required attributes
        	
        	
        	wavelength_arr = PyObject_GetAttrString(current_ref, "wavelengths");
        	counts_arr = PyObject_GetAttrString(current_ref, "counts");
        	
        	//TODO - check that numpy array has correct dtype and is contiguous
        	
        	ref_ptrs[i] = (double *)PyArray_DATA(counts_arr);
        	ref_wavelength_ptrs[i] = (double *)PyArray_DATA(wavelength_arr);
        	ref_lengths[i] = PyArray_DIM(counts_arr, 0);
        	
        	Py_DECREF(counts_arr);
        	Py_DECREF(wavelength_arr);
        	Py_DECREF(current_ref);
        }
        
        obj->fit_window_length = DIM1;
        obj->__sns_data = createSNSDataObj(ref_ptrs, obj->num_refs, ref_wavelength_ptrs, ref_lengths, IN_ARRAY1, DIM1);
        
        //now free the refs and ref_wavelengths data
        free(ref_ptrs);
        free(ref_wavelength_ptrs);
        free(ref_lengths);
        
        return obj;
        };
    
    ~ShiftAndSqueezer(){
        destroySNSDataObj(&($self->__sns_data));
        free($self);
        }
    
    PyObject * shift_and_squeeze(const double shift, const double squeeze, const int ref_num){
        
        double *result = malloc($self->fit_window_length * sizeof(double));
        npy_intp dims[1] = {$self->fit_window_length};
        
        if (result == NULL){
        	//TODO - set pyerr
        	return NULL;
        }
        
        //calculate the shifted and squeezed spectrum
        if (shiftAndSqueeze($self->__sns_data, shift, squeeze, ref_num, result) != 0){
        	free(result);
        	//TODO- set pyerr?
        	return NULL;
        }
    	
    	return createAutoDeallocNumpyArray(1, dims, NPY_DOUBLE, (void *)result);
    }
    

}
